package com.soso.base.google.comm.impl;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;

import com.soso.base.exception.unchecked.GeneralExceptionHandler;
import com.soso.base.google.comm.BaseService;
import com.soso.base.util.log.Logger;


public class BaseServiceImpl implements BaseService{
	private static BaseService baseService = null;
	private PersistenceManagerFactory pmFactory = null;
	
	private BaseServiceImpl(){
	}
	public synchronized static BaseService getInstance(){
		if(baseService==null){
			baseService=new BaseServiceImpl();
		}
		return baseService;
	}
	
	public PersistenceManagerFactory getPmFactory() {
		return pmFactory;
	}
	public void setPmFactory(PersistenceManagerFactory pmFactory) {
		this.pmFactory = pmFactory;
	}
	
	public synchronized final PersistenceManager getPm() {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		return pm;
	}

	public final void create(Object obj) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		try {
			this.create(pm,obj);
		} finally{
			pm.close();
		}
	}
	public final void createAll(List<?> list) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		try {
			this.createAll(pm, list);
		} finally{
			pm.close();
		}
	}
	public final void delete(Object obj){
		PersistenceManager pm=pmFactory.getPersistenceManager();
		try {
			this.delete(pm, obj);
		} finally{
			pm.close();
		}
	}
	public final Object deleteByPK(Class<?> clazz,Object id){
		PersistenceManager pm=pmFactory.getPersistenceManager();
		Object obj=null;
		try {
			obj = this.deleteByPK(pm, clazz, id);
		} finally{
			pm.close();
		}
		return obj;
	}
	public final void deleteAll(List<?> list) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		try {
			this.deleteAll(pm, list);
		} finally{
			pm.close();
		}
	}
	public final Long deleteAll(String GQL){
		PersistenceManager pm=pmFactory.getPersistenceManager();
		Long v=null;
		try {
			v=this.deleteAll(pm, GQL);
		} finally{
			pm.close();
		}
		return v;
	}
	public final Long deleteAll(String GQL,int startIndex,int endIndex) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		try {
			return this.deleteAll(pm, GQL, startIndex, endIndex);
		} finally{
			pm.close();
		}
	}
	
	public final Object update(Object obj) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		try {
			return this.update(pm, obj);
		} finally{
			pm.close();
		}
	}
	public final void updateAll(List<?> list) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		try {
			this.updateAll(pm, list);
		} finally{
			pm.close();
		}
	}
	public final Object update(Class<?> clazz,Object id,Object pojo) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		try {
			return this.update(pm, clazz, id, pojo);
		}  finally{
			pm.close();
		}
	}
	
	public final Object getByPK(Class<?> clazz,Object pk) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		Object obj=null;
		try {
			obj = this.getByPK(pm, clazz, pk);
		} finally{
			pm.close();
		}
		return obj;
	}
	
	public final List<?> query(String GQL, Object ...aobj){
		PersistenceManager pm=pmFactory.getPersistenceManager();
		List<Object> list=new ArrayList<Object>();
		try {
			list.addAll(this.query(pm, GQL, aobj));
		} finally{
			pm.close();
		}
		return list;
	}
	
	public final List<?> query(String GQL) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		List<Object> list=new ArrayList<Object>();
		try {
			list.addAll(this.query(pm, GQL));
		} finally{
			pm.close();
		}
		return list;
	}
	
	/**
	 * query.setRange(5, 10);
	 * For example, a range of 5, 10 returns the 6th, 7th, 8th, 9th and 10th results.
	 */
	public final List<?> query(String GQL ,int startIndex,int endIndex) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		List<Object> list=new ArrayList<Object>();
		try {
			list.addAll(this.query(pm, GQL, startIndex, endIndex));
		} catch(Exception e){
			GeneralExceptionHandler.handle("查询数据失败.",e);
		}  finally{
			pm.close();
		}
		return list;
	}
	public final int count(String GQL ,int startIndex,int endIndex) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		Integer count=0;
		try {
			count = this.count(pm, GQL, startIndex, endIndex);
		} catch(Exception e){
			GeneralExceptionHandler.handle("统计数据失败.",e);
		}  finally{
			pm.close();
		}
		return count;
	}

	public final int count(String GQL) {
		PersistenceManager pm=pmFactory.getPersistenceManager();
		Integer count=0;
		try {
			count = this.count(pm, GQL);
		} catch(Exception e){
			GeneralExceptionHandler.handle("统计数据失败.",e);
		}  finally{
			pm.close();
		}
		return count;
	}
	@Override
	public final void create(PersistenceManager pm, Object obj) {
		try {
			pm.makePersistent(obj);
		} catch(Exception e){
			GeneralExceptionHandler.handle("添加数据失败.",e);
		}
	}
	@Override
	public final void createAll(PersistenceManager pm, List<?> list) {
		try {
			pm.makePersistentAll(list);
		} catch(Exception e){
			GeneralExceptionHandler.handle("添加数据失败.",e);
		}
	}
	@Override
	public final void delete(PersistenceManager pm, Object obj) {
		try {
			pm.deletePersistent(pm.makePersistent(obj));
		} catch(Exception e){
			GeneralExceptionHandler.handle("删除数据失败.",e);
		} 
	}
	@Override
	public Object deleteByPK(PersistenceManager pm, Class<?> clazz, Object id) {
		Object obj=pm.getObjectById(clazz, id);
		if(obj==null){
			GeneralExceptionHandler.handle("没有找到与主键相对应的数据.");
		}
		try {
			pm.deletePersistent(obj);
		} catch(Exception e){
			GeneralExceptionHandler.handle("删除数据失败.",e);
		} 
		return obj;
	}
	@Override
	public final Long deleteAll(PersistenceManager pm, String GQL) {
		Long v=null;
		try {
			Query query=pm.newQuery(GQL);
			v=query.deletePersistentAll();
		} catch(Exception e){
			GeneralExceptionHandler.handle("删除数据失败.",e);
		}
		return v;
	}
	@SuppressWarnings("unchecked")
	@Override
	public final Long deleteAll(PersistenceManager pm, String GQL, int startIndex,
			int endIndex) {
		List<Object> list=null;
		try {
			Query query=pm.newQuery(GQL);
			query.setRange(startIndex, endIndex);
			list=(List<Object>)query.execute();
			query.closeAll();
		} catch(Exception e){
			GeneralExceptionHandler.handle("查询数据失败.",e);
		}
		if(list==null || list.isEmpty()){
			return 0L;
		}
		try {
			pm.deletePersistentAll(list);
		} catch(Exception e){
			GeneralExceptionHandler.handle("删除数据失败.",e);
		}
		return (long)list.size();
	}
	@Override
	public final void deleteAll(PersistenceManager pm, List<?> list) {
		try {
			pm.deletePersistentAll(list);
		} catch(Exception e){
			GeneralExceptionHandler.handle("删除数据失败.",e);
		} 
	}
	@Override
	public final Object update(PersistenceManager pm, Object obj) {
		try {
			pm.makePersistent(obj);
		} catch(Exception e){
			GeneralExceptionHandler.handle("更新数据失败.",e);
		} 
		return obj;
	}
	@Override
	public final void updateAll(PersistenceManager pm, List<?> list) {
		try {
			pm.makePersistentAll(list);
		} catch(Exception e){
			GeneralExceptionHandler.handle("更新数据失败.",e);
		} 
	}
	@Override
	public final Object update(PersistenceManager pm, Class<?> clazz, Object id,
			Object pojo) {
		Object obj=pm.getObjectById(clazz, id);
		if(obj==null){
			GeneralExceptionHandler.handle("没有找到与主键相对应的数据.");
		}
		try{
			Method[] methods=clazz.getDeclaredMethods();
			String field=null;
			for(Method method:methods){
				if(method.getName().startsWith("get")){
					Object value=method.invoke(pojo);
					if(value!=null){
						field=method.getName().substring(3);
						field="set"+field;
						method=clazz.getDeclaredMethod(field, method.getReturnType());
						method.invoke(obj, value);
					} 
				}
			}
		}catch(Exception e){
			GeneralExceptionHandler.handle("给属性赋值失败,信息："+e.getMessage());
		}
		return obj;
	}
	@Override
	public final int count(PersistenceManager pm, String GQL) {
		Integer count=0;
		try {
			Query query=pm.newQuery(GQL);
			query.setResult("count(this)");
			Object ob=query.execute();
			count=(Integer)ob;
			query.closeAll();
		} catch(Exception e){
			GeneralExceptionHandler.handle("查询数据失败.",e);
		}
		return count;
	}
	@Override
	public final int count(PersistenceManager pm, String GQL, int startIndex,
			int endIndex) {
		Integer count=0;
		try {
			Query query=pm.newQuery(GQL);
			query.setResult("count(this)");
			query.setRange(startIndex, endIndex);
			Object ob=query.execute();
			count=(Integer)ob;
			query.closeAll();
		} catch(Exception e){
			GeneralExceptionHandler.handle("查询数据失败.",e);
		}
		return count;
	}
	@Override
	public final Object getByPK(PersistenceManager pm, Class<?> clazz, Object pk) {
		Object obj=null;
		try {
			obj=pm.getObjectById(clazz,pk);
		} catch(JDOObjectNotFoundException e){
			Logger.warn(e.getMessage());
		}
		return obj;
	}
	@SuppressWarnings("unchecked")
	@Override
	public final List<?> query(PersistenceManager pm, String GQL, int startIndex,
			int endIndex) {
		List<Object> list=new ArrayList<Object>();
		try {
			Query query=pm.newQuery(GQL);
			query.setRange(startIndex, endIndex);
			list.addAll((List<Object>)query.execute());
			query.closeAll();
		} catch(Exception e){
			GeneralExceptionHandler.handle("查询数据失败.",e);
		}
		return list;
	}
	@SuppressWarnings("unchecked")
	@Override
	public final List<?> query(PersistenceManager pm, String GQL, Object... aobj) {
		List<Object> list=new ArrayList<Object>();
		try {
			Query query=pm.newQuery(GQL);
			list.addAll((List<Object>)query.executeWithArray(aobj));
			query.closeAll();
		} catch(Exception e){
			GeneralExceptionHandler.handle("查询数据失败.",e);
		}
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public final List<?> query(PersistenceManager pm,String GQL) {
		List<Object> list=new ArrayList<Object>();
		try {
			Query query=pm.newQuery(GQL);
			list.addAll((List<Object>)query.execute());
			query.closeAll();
		} catch(Exception e){
			GeneralExceptionHandler.handle("查询数据失败.",e);
		}
		return list;
	}
	

}
